來到了第四章(快過半了,加油!),今天我們要進入到介面的世界,介面到底扮演什麼樣的角色?物件之間又是如何藉由介面去溝通呢?根據前三章所學,我們可以先歸納出三個要點:
物件導向程式設計不僅僅是關於類別的定義,它更關注物件之間的互動和訊息傳遞,並通過介面實現彈性設計,使應用程式能夠不斷增長和適應變化。
假設有兩支正在執行的應用程式,應用程式包含了許多物件,訊息在這些物件之間傳遞。
(圖片拍攝自書籍:Practical Object-Oriented Design in Ruby: An Agile Primer)
在第一支應用程式裡,每一個類別都暴露了所有的內容。任何類別裡的任何方法都可以隨意被其他任 何物件使用;在第二支應用程式裡,訊息模式明顯,每一個物件都有一套明確定義的方法,並期望其他物件去使用它們。 這些暴露出的方法構成了類別的公共介面。
「介面」一詞可以指代許多不同的概念。在此處指的是類別裡的介面(方法)。類別實作了方法,有些方法旨在被其他物件使用,而這些方法便組成了它的公共介面。
假設有一間餐廳廚房。顧客根據菜單來點餐。這間廚房做了許多事情,但是它沒有將這些內容都暴露給顧客(謝天謝地)。它擁有 一個公共介面提供給顧客使用,也就是菜單。在廚房裡,可能發生了很多事情,有許多其他的訊息在傳遞。但是,這些訊息是私有的,因此顧客看不到它們。
文字說明可能過於抽象,實作一個簡單的範例:
class Restaurant
def initialize
@menu = {
"burger" => 10,
"pizza" => 12,
"spaghetti" => 15
}
end
def display_menu
puts "Menu:"
@menu.each do |item, price|
puts "#{item}: $#{price}"
end
end
def place_order(item)
if @menu.key?(item)
puts "Order for #{item} received."
prepare_order(item)
else
puts "Sorry, we don't have #{item} on the menu."
end
end
private
def prepare_order(item)
puts "Preparing #{item}..."
# 廚房內部處理訂單的邏輯
puts "#{item} is ready. Enjoy your meal!"
end
end
# 顧客點餐
restaurant = Restaurant.new
restaurant.display_menu
restaurant.place_order("burger")
restaurant.place_order("sushi") # 菜單上沒有壽司
公共介面(Public method)
類別所呈現與傳達給外界的方法。
私有介面(Private method)
類別裡獨自運作而不需要被知道的方法。
第二章關注建立具有單一職責的類別,即每個類別應該有一個單一的目的,並且其公共方法應該反映這個目的。每個類別的具體職責與其公共方法之間應該存在對應關係。公共方法構成了類別的公共接口,它們描述了類別的職責。
第三章關注依賴關係管理,強調類別應該只依賴於比自己更穩定的類別。類別被劃分為公共和私有部分,其中公共部分是穩定的,私有部分是可變的。當類別使用其他類別的公共方法時,它表明它信任這些方法是穩定的。然而,當它依賴其他類別的私有方法時,它應該意識到這種依賴會增加風險,因為私有方法可能不夠穩定,受到不相關的變化的影響。這強調了依賴關係的管理對於系統的穩定性和可維護性至關重要。
通常情況下,我們不應該依賴於其他類的私有方法,因為這會破壞封裝性和隔離性。如果一個類的私有方法需要被其他類使用,考慮將這些方法改為受保護或公共方法,或者通過其他方式提供對其功能的使用。
今天先初步理解介面,明天我們繼續了解介面的使用與迪米特法則,晚安~
參考資料: